package day16;

import jdk.Exported;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/*本类用于测试自定义注解*/
public class TestAnnotation { }


/*1.2 通过@Target注解表示此自定义注解可以使用的位置
* 注意:@Target注解使用时需要导包,我们通过"ElementType.静态常量值"的方式来指定
* 此自定义注解可以使用的位置
* 如果有多个值,可以使用"{ , }"的格式来写:@Target({ElementType.METHOD,ElementType.TYPE})*/
@Target({ElementType.METHOD,ElementType.TYPE,ElementType.FIELD})//表示此注解可以加在方法上
/*1.3通过@Retention注解表示自定义注解的生命周期
* 注意:@Retention使用时也需要导包,通过RetentionPolicy.静态常量值来指定此自定义注解的生命周期
* 也就是指自定义注解可以存在在哪个文件中:源文件中/字节码文件中/运行时有效
* 而且这三个值,只能3选1,不能同时写多个*/
@Retention(RetentionPolicy.SOURCE)
/*0.首先注意:自定义注解的语法与java不同,不要套用java的格式*/
//1.定义自定义主解,注解名是Test,并通过两个元注解表示此注解的作用位置和生命周期
/*1.注解定义要使用"@interface 注解名"的方式来定义*/
@interface Test{
    /*3.自定义注解还可以添加功能--给注解添加属性
    * 注意 int age();不是方法的定义,而是给自定义注解中定义age属性的语法
    * 如果为了使用注解时方便,还可以给属性指定默认值,这样就可以直接使用,格式:int age() default 0;
    * */
    //int age(); //给注解定义一个普通的属性age
    int age() default 0;
    /*4.注解中还可以添加功能-可以定义特殊属性value
    * 特殊属性的定义方式与别的属性相同,主要是使用方式不同
    * 使用此注解给属性赋值的时候,可以不用写成"@Test(value = "Apple")",
    * 格式可以简化"@Test("Apple")"直接写值
    * 但是自定义注解类中的赋予默认值不可以简写,如果自定义了默认值,可以不用赋值,直接使用*/
    String value() default "apple";
}
/*2.使用注解时,只要在指定的自定义注解名字前加上"@"即可使用此注解*/
//2.定义一个类用来测试自定义注解
//@Test
class TeatAnno{
    /*测试1:分别给TestAnno类/name属性/eat()都添加了@Test注解,只有方法上不报错
    * 结论:自定义注解能够加在什么位置,取决于@Target注解的值
    * 测试2:修改@Target注解的值:@Target({ElementType.METHOD,ElementType.TYPE,ElementType.FIELD})
    * 结论:注解@Test可以存在于多个位置,如果@Target有多个值,格式是"{ , }"
    * 原因:Target注解的源码:ElementType[] value();*/
    //@Test
    String name;
    /*测试3:当我们添加了注解的age属性时,@Test注解报错
    * 结论:当注解没有定义属性时,可以直接使用,如果有属性了,就需要给属性赋值
    * 测试4:给@Test注解的age属性赋值以后,就不报错了
    * 结论:给属性赋值的格式" @Test(age = 10)",注意,不能直接写10,这是错误格式
    * 测试5:给age属性赋予默认值后,可以不加属性值,直接使用注解,此时使用的就是age的默认值
    * */
    /*测试6:给特殊属性value赋值时可以简写,想当于value="apple"*/
    @Test/*测试7:因为已有默认值,所以不用给特殊属性赋值,直接使用@Test*/
    //@Test(age = 10)
    public void eat(){
        System.out.println("又到干饭时间啦~");
    }
}